package patrol.mobile.com.mobilepatrol.utils.net;


import android.app.ProgressDialog;
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;

import com.zhy.http.okhttp.BuildConfig;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.builder.GetBuilder;
import com.zhy.http.okhttp.builder.PostFormBuilder;
import com.zhy.http.okhttp.callback.StringCallback;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import patrol.mobile.com.mobilepatrol.R;
import patrol.mobile.com.mobilepatrol.utils.Constants;
import patrol.mobile.com.mobilepatrol.utils.GsonUtil;
import patrol.mobile.com.mobilepatrol.utils.SPUtils;
import patrol.mobile.com.mobilepatrol.utils.StringUtils;

/**
 * 网络请求
 * 1. 支持 get/post 请求
 * 2. 调用请求的时候可以弹出 Loading dialog
 * <h3>目标</h3>
 * 1. ****
 * <h3>不足</h3>
 * 1. 当前参数的 value 为字符串类型，应修改为参数的自然类型。
 *
 * @author K
 */
public final class HttpSender {
    private static final String TAG = "HttpSender";

    private Context context;
    private String host;
    private String url;
    private String title;
    private ProgressDialog dialog;
    private Boolean isShowDialog = true;
    private String LOADING_TITLE;
    private String baseUrl;

    private HttpSender() {
        throw new IllegalArgumentException();
    }


    public HttpSender(Context context, String host, String url) {
        this(context, host, url, true);
    }

    public HttpSender(Context context, String host, String url, boolean isShowDialog) {
        this.context = context;
        this.host = host;
        this.url = url;
//        this.mode = mode;
        this.isShowDialog = isShowDialog;
        if (isShowDialog && context != null) {
            LOADING_TITLE = "加载中...";
        }
    }

    public Context getContext() {
        return context;
    }

    /**
     * 设置对话框提示内容
     */
    public void setDialogTitle(String title) {
        this.title = title;
    }

    /**
     * 发送一个有且只有一个参数的 get 请求。如果需要发送不带参数的请求，使用{@link #requestGet(HashMap, HttpCallBack)}
     *
     * @param key      参数名
     * @param param    参数值
     * @param callBack 请求结果回调
     */
    public void requestGet(@NonNull String key, @NonNull String param, HttpCallBack callBack) {
//        if (!NetUtils.isConnect(MyApplication.getInstance())) {
//            callBack.onError(null, null, -18);
//            return;
//        }
        showDialog();
        String realUrl = host + url;
        Log.i(TAG, "-------------------------------------------------------------------------");
        Log.i(TAG, "Http URL:" + realUrl + " {" + key + ":" + param + "}");
        Log.i(TAG, "-------------------------------------------------------------------------");

        GetBuilder builder = OkHttpUtils.get().url(realUrl);
//        builder.addHeader("User-Agent", generateHeader());
        builder.addParams(key, param);
        builder.build().execute(callBack);
    }

    /**
     * 发送一个有多个参数的 get 请求。参数允许为 null，表示发送一个不带任何参数的请求。
     *
     * @param params   参数集合
     * @param callBack 请求结果回调
     */
    public void requestGet(@Nullable HashMap<String, String> params, @NonNull HttpCallBack callBack) {
//        if (!NetUtils.isConnect(MyApplication.getInstance())) {
//            callBack.onError(null, null, -18);
//            return;
//        }
        showDialog();
        initGetParam(params).build().execute(callBack);
    }

    private GetBuilder initGetParam(@Nullable HashMap<String, String> params) {
        String realUrl = host + url;
        //
        if (params == null) {
            return OkHttpUtils.get().url(realUrl);
        }
        GetBuilder builder = OkHttpUtils.get().url(realUrl);
//        builder.addHeader("User-Agent", generateHeader());
        builder.params(params);
        Log.i(TAG, "-------------------------------------------------------------------------");
        Log.i(TAG, "Http URL FOR GET :" + realUrl + params);
        Log.i(TAG, "-------------------------------------------------------------------------");

        return builder;
    }

    /**
     * 发送一个有且只有一个参数的 post 请求
     *
     * @param key      参数名
     * @param param    参数值
     * @param callBack 请求结果回调
     */
    public void requestPost(@NonNull String key, @NonNull String param, @NonNull HttpCallBack callBack) {
//        if (!NetUtils.isConnect(MyApplication.getInstance())) {
//            callBack.onError(null, null, -18);
//            return;
//        }
        showDialog();
        String realUrl = host + url;
        Log.i(TAG, "-------------------------------------------------------------------------");
        Log.i(TAG, "Http URL:" + realUrl + " {" + key + ":" + param + "}");
        Log.i(TAG, "-------------------------------------------------------------------------");

        PostFormBuilder builder = OkHttpUtils.post().url(realUrl);
        builder.addHeader("User-Agent", generateHeader());
        builder.addParams(key, param);
        builder.build().execute(callBack);
    }

    /**
     * 发送一个有多个参数的 post 请求
     *
     * @param params   参数集合
     * @param callBack 请求结果回调
     */
    public void requestPost(@NonNull HashMap<String, String> params, @NonNull StringCallback callBack) {
        Log.e("传递参数", GsonUtil.mapString2Json(params));
        showDialog();
        initPostParam(params).build().execute(callBack);
    }

    public static void postImage(String realUrl, HashMap<String, Object> paramsMap, @NonNull Callback callback) {
        OkHttpClient client = new OkHttpClient();
        MultipartBody.Builder builder = new MultipartBody.Builder();
        //设置类型
        builder.setType(MultipartBody.FORM);
        for (String key : paramsMap.keySet()) {
            Object object = paramsMap.get(key);
            if (!(object instanceof byte[])) {
                builder.addFormDataPart(key, object.toString());
            } else {
                byte[] file = (byte[]) object;
                builder.addFormDataPart(key, "1.jpg", RequestBody.create(MediaType.parse("image/jpeg"), file));
            }
        }
        RequestBody body = builder.build();
        //创建Request
        Request request = new Request.Builder().url(realUrl).post(body).build();
        Call call = client.newBuilder().writeTimeout(1000, TimeUnit.SECONDS).build().newCall(request);
        call.enqueue(callback);
    }

    public void postJson(@NonNull String json, @NonNull StringCallback callback) {
        String realUrl = host + url;
        Log.i(TAG, "-------------------------------------------------------------------------");
        Log.i(TAG, "Http URL:" + realUrl + "\n" + json);
        Log.i(TAG, "-------------------------------------------------------------------------");
        OkHttpUtils.postString()
                .url(realUrl)
                .content(json)
                .mediaType(MediaType.parse("application/json; charset=utf-8"))
                .build()
                .execute(callback);
    }

    /**
     * 上传图片
     *
     * @param files    文件list
     * @param params   参数
     * @param callback 回调
     */
    public void upImgs(List<File> files, Map<String, String> params, StringCallback callback) {
        String realUrl = host + url;
        Log.i(TAG, "-------------------------------------------------------------------------");
        Log.i(TAG, "Http URL:" + realUrl + "\n" + params.toString());
        Log.i(TAG, "-------------------------------------------------------------------------");
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Disposition", "form-data;filename=enctype");
        PostFormBuilder builder = OkHttpUtils.post();
        builder.url(host + url);
        for (int i = 0; i < files.size(); i++) {
            File file = files.get(i);
            if (!file.exists()) {
                Toast.makeText(context, "文件不存在，请修改文件路径", Toast.LENGTH_SHORT).show();
                return;
            }
            String filename = file.getName();
            Log.i(TAG, "filename:" + filename);
            Log.i(TAG, "filePath:" + file.getPath());
            builder.addFile("mFile" + i, filename, file);
        }

        builder.params(params)
                .headers(headers)
                .build()
                .execute(callback);
    }

    /**
     * 上传图片
     *
     * @param file    文件
     * @param params   参数
     * @param callback 回调
     */
    public void upImgs2(File file, Map<String, String> params, StringCallback callback) {
        String realUrl = host + url;
        Log.i(TAG, "-------------------------------------------------------------------------");
        Log.i(TAG, "Http URL:" + realUrl + "\n" + params.toString());
        Log.i(TAG, "-------------------------------------------------------------------------");
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Disposition", "form-data;filename=enctype");
        PostFormBuilder builder = OkHttpUtils.post();
        builder.url(host + url);
                builder.addFile("files",file.getName(),file)
                .params(params)
                .headers(headers)
                .build()
                .execute(callback);
    }

    private PostFormBuilder initPostParam(@NonNull HashMap<String, String> params) {
        String realUrl = host + url;
        PostFormBuilder builder = OkHttpUtils.post().url(realUrl);
        builder.addHeader("User-Agent", generateHeader());
        builder.params(params);

        Log.i(TAG, "-------------------------------------------------------------------------");
        Log.i(TAG, "Http URL FOR POST :" + realUrl);
        Log.i(TAG, "Http PARAMS:");
        Set<Map.Entry<String, String>> set = params.entrySet();
        for (Map.Entry<String, String> e : set) {
            Log.i(TAG, e.getKey() + "  :  " + e.getValue());
        }
        Log.i(TAG, "-------------------------------------------------------------------------");

        return builder;
    }

    private void showDialog() {
        if (!isShowDialog || context == null) {
            return;
        }
        if (dialog == null) {
            dialog = new ProgressDialog(context);
            String title = StringUtils.isEmpty(this.title) ? LOADING_TITLE : this.title;
            dialog.setMessage(title);
        }
        dialog.setCancelable(false);
        dialog.setCanceledOnTouchOutside(false);
        dialog.show();
    }

    public void dismissDialog() {
        if (dialog != null && dialog.isShowing())
            dialog.dismiss();
    }

    private static final String SPL_CHAR = "; ";

    /**
     * 生成 User-Agent 请求头。格式: 应用名称:版本号/版本名; 安卓版本; 设备分辨率。
     */
    private String generateHeader() {
        StringBuilder sb = new StringBuilder("App-Agent: ZRWUFUMONEY");
        try {
            sb.append(BuildConfig.VERSION_CODE)
                    .append("/")
                    .append(BuildConfig.VERSION_NAME)
                    .append(SPL_CHAR)
                    .append("Android")
                    .append(Build.VERSION.SDK_INT)
                    .append(SPL_CHAR)
                    .append(Build.MANUFACTURER)
                    .append(SPL_CHAR);
            Log.d(TAG, "generateHeader : " + sb.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }
}